﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows;
using System.Xml.Serialization;
using System.Linq;

namespace WebsiteLoadTool.Configuration
{
    public static class DataFileHelper
    {
        public static ObservableCollection<Website> LoadWebsites()
        {
            ObservableCollection<Website> websites = new ObservableCollection<Website>();

            try
            {
                string websitesFile = ConfigSettingHelper.ReadSetting("Websites");
                if (!File.Exists(websitesFile))
                {
                    WriteWebsites(websites);
                }
                else
                {
                    lock (typeof(DataFileHelper))
                    {

                        using (Stream str = File.Open(ConfigSettingHelper.ReadSetting("Websites"), FileMode.OpenOrCreate))
                        {
                            XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<Website>));
                            websites = (ObservableCollection<Website>)serializer.Deserialize(str);
                            str.Close();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error loading websites", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            return websites;
        }

        public static bool LoadWebsiteResults(ObservableCollection<Website> websites)
        {
            try
            {
                foreach (Website site in websites)
                {
                    string siteLogFile = string.Format(ConfigSettingHelper.ReadSetting("Results"), site.ID);

                    if (!File.Exists(siteLogFile))
                    {
                        WriteWebsiteResults(site);
                    }
                    else
                    {
                        lock (typeof(DataFileHelper))
                        {
                            using (Stream str = File.Open(siteLogFile, FileMode.OpenOrCreate))
                            {
                                XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<WebsiteLoadResult>));
                                site.Results = (ObservableCollection<WebsiteLoadResult>)serializer.Deserialize(str);
                                str.Close();
                            }
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error reading results", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            return true;
        }

        public static bool WriteWebsites(ObservableCollection<Website> websites)
        {
            try
            {
                lock (typeof(DataFileHelper))
                {
                    string websitesFile = ConfigSettingHelper.ReadSetting("Websites");

                    File.Delete(websitesFile);

                    using (Stream str = File.Open(websitesFile, FileMode.OpenOrCreate))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<Website>));
                        serializer.Serialize(str, websites);
                        str.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error writing websites", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            return true;
        }

        public static bool WriteWebsiteResults(ObservableCollection<Website> websites)
        {
            try
            {
                foreach (Website site in websites)
                    WriteWebsiteResults(site);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error writing websites", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            return true;
        }


        public static bool WriteWebsiteResults(Website website)
        {
            try
            {
                lock (typeof(DataFileHelper))
                {
                    string siteLogFile = string.Format(ConfigSettingHelper.ReadSetting("Results"), website.ID);

                    File.Delete(siteLogFile);

                    using (Stream str = File.Open(siteLogFile, FileMode.OpenOrCreate))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<WebsiteLoadResult>));
                        serializer.Serialize(str, website.Results);
                        str.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), string.Format("Error writing website {0}", website.Name), MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            return true;
        }

        public static void WriteLogEntry(string entry)
        {
            Observable.Start<bool>(
                new Func<bool>(
                    () =>
                    {
                        string logFile = ConfigSettingHelper.ReadSetting("LogPath");

                        if (!File.Exists(logFile))
                        {
                            using (StreamWriter str = File.CreateText(logFile))
                            {
                                str.WriteLine(entry);
                                str.Close();
                            }
                        }
                        else
                        {
                            using (StreamWriter str = File.AppendText(logFile))
                            {
                                str.WriteLine(entry);
                                str.Close();
                            }
                        }

                        return true;
                    }))
                    .SubscribeOnDispatcher()
                    .Subscribe(
                    (success) =>
                    {
                        //Whatever. The log is written;
                    },
                    (exception) =>
                    {
                        MessageBox.Show(exception.Message, "Error writing log file", MessageBoxButton.OK, MessageBoxImage.Error);
                    });
        }
    }
}
